﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using LayerEntity.Persona.RecursosHumanos;

namespace LayerEntity.Persona.BaseClass
{
     internal  class EPersona : IEPersona
    {
        #region Variables
        List<EContacto> listCon = new List<EContacto>();
        List<EDireccion> listDir = new List<EDireccion>();        
        List<ECuentasCorrientes> listCta = new List<ECuentasCorrientes>();
        EPlanilla info = new EPlanilla();
        #endregion

        #region Constructores
        /// <summary>
        /// Inicializa la Clase Base <see cref="EPersona"/>
        /// </summary>
        public EPersona()
        {
            Inicializar();
        }
        
        /// <summary>
        /// Inicializa la Clase Base <see cref="EPersona"/> con un <see cref="IDataRecord "/>
        /// </summary>
        /// <param name="record">
        /// <see cref="IDataRecord "/> con la Informacion de la Persona.
        /// </param>
        public EPersona(IDataRecord record)
        {
            Inicializar();
            this.IdPersona = record["id_persona"].ToString();
            this.IdTipoDocumento =(int) record ["id_documento"];
            this.NumeroDocumento = record["doc_persona"].ToString ();
            if (record["rs_persona"] !=  DBNull.Value )
            {
                
                this.RazonSocial = record ["rs_persona"].ToString ();
            }
            if (record["nom_com_persona"] != DBNull.Value )
            {
                this.NombreComercial =  record ["nom_com_persona"].ToString ();
            }
            if (record["nom_persona"] != DBNull.Value )
            {
                this.Apellidos =  record ["nom_persona"].ToString ();
            }
            if (record["ape_persona"] != DBNull.Value )
            {
                this.Nombres = record["ape_persona"].ToString();
            }

            this.TipoPersonaSistema = record["tipo_per_sistema"].ToString();

            this.Observacion =  record ["obs_presona"].ToString();
            this.IdEstado = int.Parse ( record ["id_estado"].ToString ());
            if (record["lug_naci_persona"] != DBNull.Value )
            {
                this.LugarNacimiento = record ["lug_naci_persona"].ToString ();
            }
            if (record["sex_persona"] != DBNull.Value)
            {
                this.Sexo = (int)record["sex_persona"];
            }
            this.FullName =  record ["fullname_persona"].ToString ();
            if (record["id_tipo_cliente"] != DBNull.Value ) {
                IdTipoCliente = (int)record["id_tipo_cliente"];
            }
            if (record["noaptocredito"] != DBNull.Value )
            {
                this.CreditoNoDisponible = Convert.ToBoolean((int)record["noaptocredito"]);
            }
            if (record["deuda_confidencial"] != DBNull.Value )
            {
                int valor2 = (int)record["deuda_confidencial"];
                this.IsDeudaConfidencial = Convert.ToBoolean(valor2);
            }
            if (record["id_tipo_proveedor"] != DBNull.Value )
            {
                this.IdTipoProveedor = Convert.ToInt32 (record ["id_tipo_proveedor"]);
            }
            if (record["id_profesion"] != DBNull.Value )
            {
                this.IdProfesion =  (int)record ["id_profesion"];
            }
            if (record["id_gradoinstruccion"] != DBNull.Value )
            {
                this.IdGradoInstruccion =  (int)record ["id_gradoinstruccion"];
            }
            if (record["est_civ_persona"] != DBNull.Value )
            {
                this.IdEstadoCivil = (int)record["est_civ_persona"];
            }
            if (record["id_area"] != DBNull.Value )
            {
                this.IdArea = (int)record["id_area"];
            }
            if (record["id_cargo"] != DBNull.Value )
            {
                this.IdCargo =  (int)record ["id_cargo"];
            }
            if (record["fecnac_persona"] != DBNull.Value ) {
                this.FechaNacimiento = (DateTime)record["fecnac_persona"];
            }            
           this.Imagen =null ;
            this.listCon = new List<EContacto>();
            this.listDir = new List<EDireccion>();
            this.Planilla = new RecursosHumanos.EPlanilla();
            this.listCta = new List<ECuentasCorrientes>();
        }

        #endregion

        #region Propiedades
       
        /// <summary>
        /// Id Unico de la Persona Registrada
        /// </summary>
        public string IdPersona { get; set; }

        /// <summary>
        /// Id del documento de Identificacion
        /// </summary>
        public int IdTipoDocumento { get; set; }

        /// <summary>
        /// Numero del Documento de Identificacion
        /// </summary>
        public string NumeroDocumento { get; set; }

        /// <summary>
        /// Razon Social de la Persona
        /// </summary>
        public string RazonSocial { get; set; }

        /// <summary>
        /// Nombre Comercial de la Persona
        /// </summary>
        public string NombreComercial { get; set; }

        /// <summary>
        /// Apellidos de la Persona a registrar
        /// </summary>
        public string Apellidos { get; set; }

        /// <summary>
        /// Nombres de la persona a registrar
        /// </summary>
        public string Nombres { get; set; }

        /// <summary>
        /// Identificador unico de Tipo de Persona
        /// </summary>
        public string TipoPersonaSistema { get; set; }

        /// <summary>
        /// Observaciones realizadas
        /// </summary>
        public string Observacion { get; set; }

        /// <summary>
        /// Id Estado de la Persona
        /// </summary>
        public int IdEstado { get; set; }

        /// <summary>
        /// Fecha de Nacimiento, valido solo para Clientes y Empleados
        /// </summary>
        public DateTime FechaNacimiento { get; set; }

        /// <summary>
        /// Lugar de Nacimiento, valido solo para Clientes y Empleados
        /// </summary>
        public string LugarNacimiento { get; set; }

        /// <summary>
        /// Sexo de la Persona, valido solo para Clientes y Empleados
        /// </summary>
        public int Sexo { get; set; }

        /// <summary>
        /// FullName de la Persona
        /// </summary>
        public string FullName { get; set; }

        /*Propiedades de Clientes*/
        /// <summary>
        /// Id de Tipo de Cliente.
        /// </summary>
        public int IdTipoCliente { get; set; }

        /// <summary>
        ///Indica si un cliente (Esta o No Apto para Credito)
        /// </summary>
        public Boolean CreditoNoDisponible { get; set; }

        /// <summary>
        /// Indise si el cliente autoriza o nu la visibilidad de su Deuda.
        /// </summary>
        public Boolean IsDeudaConfidencial { get; set; }

        public int IdTipoProveedor { get; set; }

        /*Variables de Empleados*/

        /// <summary>
        /// Id de la Profesion del Empleado
        /// </summary>
        public int IdProfesion { get; set; }

        /// <summary>
        /// Id del Grado de Instrccion del Empleado
        /// </summary>
        public int IdGradoInstruccion { get; set; }

        /// <summary>
        /// Id del Estado Civil del Empleado
        /// </summary>
        public int IdEstadoCivil { get; set; }

        /// <summary>
        /// Id del Area del Empelado
        /// </summary>
        public int IdArea { get; set; }

        /// <summary>
        /// Id del Cargo del Empleado
        /// </summary>
        public int IdCargo { get; set; }

        /// <summary>
        /// Informacion de Planilla, asi el empleado no este Registrado.
        /// </summary>
        public EPlanilla Planilla
        {
            get
            {
                return this.info;
            }
            set
            {
                this.info = value;
            }
        }

        public Image Imagen { get; set; }
        #endregion

        #region Metodos

        /// <summary>
        /// Permite agregar un contacto
        /// </summary>
        /// <param name="contact">Inforacion del Contacto a agregar, no debe ser null</param>
        public void AddContactInfo(EContacto contact)
        {
            if (this.listCon == null)
            {
                this.listCon = new List<EContacto>();
            }
            if (contact != null)
            {
                this.listCon.Add(contact);
            }
        }

        /// <summary>
        /// Permite agregrar un conjunto de contactos
        /// </summary>
        /// <param name="contact">Informacion de los Contactos a agregar, no deben ser nullos.</param>
        public void AddContactInfo(List<EContacto> contact)
        {
            if (this.listCon == null)
            {
                this.listCon = new List<EContacto>();
            }
            if (contact != null)
            {
                this.listCon.AddRange(contact);
            }
        }

        /// <summary>
        /// Permite agregar una direccion.
        /// </summary>
        /// <param name="direccion">Informacion de la direccion a agregar.</param>
        public void AddAddressInfo(EDireccion direccion)
        {
            if (this.listDir == null)
            {
                this.listDir = new List<EDireccion>();
            }
            if (direccion != null)
            {
                int index = listDir.FindIndex(delegate(EDireccion d)
                {
                    return d.Item == direccion.Item;
                });
                if (index < 0)
                {
                    this.listDir.Add(direccion);
                }
                else
                {
                    listDir[index] = direccion;
                }
            }
        }

        /// <summary>
        /// Permite agregar un conjuntos de direcciones.
        /// </summary>
        /// <param name="direccion">Conjunto de Direcciones a agregar, no deben ser nulos.</param>
        public void AddAddressInfo(List<EDireccion> direccion)
        {
            if (this.listDir == null)
            {
                this.listDir = new List<EDireccion>();
            }
            if (direccion != null)
            {
                this.listDir.AddRange(direccion);
            }
        }

        /// <summary>
        /// Permite agregar informacion de una cuenta corriente.
        /// </summary>
        /// <param name="ctacte">Informacion de la cuenta corriente a agregar, no debe ser null</param>
        public void AddAccountInfo(ECuentasCorrientes ctacte)
        {
            if (this.listCta == null)
            {
                this.listCta = new List<ECuentasCorrientes>();
            }
            if (ctacte != null)
            {
                this.listCta.Add(ctacte);
            }
        }

        public void RemoveAccountInfo(ECuentasCorrientes ctacte)
        {
            if (listCta != null)
            {
                if (ctacte != null)
                {
                    listCta.Remove(ctacte);
                }
            }
        }

        /// <summary>
        /// Permite agregar un conjuntos de cuentas corrientes a un proveedor.
        /// </summary>
        /// <param name="ctacte">Informacion de las cuentas corrientes a agregar, no deben ser nulos.</param>
        public void AddAccountInfo(List<ECuentasCorrientes> ctacte)
        {
            if (this.listCta == null)
            {
                this.listCta = new List<ECuentasCorrientes>();
            }
            if (ctacte != null)
            {
                this.listCta.AddRange(ctacte);
            }
        }

        #endregion
        #region Metodos Privados
        private void Inicializar()
        {
            this.IdPersona = string.Empty;
            this.IdTipoDocumento = -1;
            this.NumeroDocumento = string.Empty;
            this.RazonSocial = string.Empty;
            this.NombreComercial = string.Empty;
            this.Apellidos = string.Empty;
            this.Nombres = string.Empty;
            this.TipoPersonaSistema = string.Empty;
            this.Observacion = string.Empty;
            this.IdEstado = -1;
            this.LugarNacimiento = string.Empty;
            this.Sexo = -1;
            this.FullName = string.Empty;
            this.IdTipoCliente = -1;
            this.CreditoNoDisponible = false;
            this.IsDeudaConfidencial = false;
            this.IdTipoProveedor = -1;
            this.IdProfesion = -1;
            this.IdGradoInstruccion = -1;
            this.IdEstadoCivil = -1;
            this.IdArea = -1;
            this.IdCargo = -1;
            this.Planilla = new RecursosHumanos.EPlanilla();
            this.Imagen = null;

            listCon = new List<EContacto>();
            listDir = new List<EDireccion>();
            listCta = new List<ECuentasCorrientes>();
        }
        #endregion
        #region Funciones

        /// <summary>
        /// Obtiene una lista de todos los contacos registrados para el proveedor actual.
        /// </summary>
        /// <returns>
        /// Un <see cref="List<EContacto>"/> con todos los contactos registrados.
        /// </returns>
        public List<EContacto> GetContacts()
        {
            return this.listCon;
        }

        /// <summary>
        /// Obtiene un contacto segun el codigo indicado.
        /// </summary>
        /// <param name="item">Id del contacto a buscar</param>
        /// <returns>Un <see cref="EContacto"/> si el Id existe, de lo contrario null.</returns>
        public EContacto GetContacts(int item)
        {
            return this.listCon.Find(delegate(EContacto info)
            {
                return (info.Item == item);
            });
        }

        /// <summary>
        /// Obtiene una lista de todas las direccione registradas.
        /// </summary>
        /// <returns>
        /// Un <see cref="List<EDireccion>"/> con las direcciones registradas.
        /// </returns>
        public List<EDireccion> GetAddress()
        {
            return this.listDir;
        }

        /// <summary>
        /// Permite Recuperar la Direccion Principal
        /// </summary>
        /// <returns></returns>
        public EDireccion GetPrincipalAddress()
        {
            EDireccion dire = new EDireccion();
            dire = this.listDir.Find(delegate(EDireccion d)
            {
                return d.IsPrincipal;
            });
            if (dire == null)
            {
                dire = new EDireccion();
            }
            return dire;
        }

        /// <summary>
        /// Obtiene una lista de direcciones segun el ubigeo indicado.
        /// </summary>
        /// <param name="strUbigeo">Ubigeo en donde se buscaran las direcciones.</param>
        /// <returns>
        /// Un <see cref="List<EDireccion>"/> con las direcciones que coinciden con el ubugeo indicado.
        /// </returns>
        public List<EDireccion> GetAddress(string strUbigeo)
        {
            return this.listDir.FindAll(delegate(EDireccion dir)
            {
                return dir.Ubigeo == strUbigeo;
            });
        }

        /// <summary>
        /// Obtiene informacion de una direccion, segun el codigo indicado.
        /// </summary>
        /// <param name="item">Id de la Direccion a buscar.</param>
        /// <returns>Un <see cref="EDireccion"/> si el Id existe, de lo contrario null.</returns>
        public EDireccion GetAddress(int item)
        {
            return this.listDir.Find(
                delegate(EDireccion dir)
                {
                    return dir.Item == item;
                });
        }

        /// <summary>
        /// Obtiene una lista de todos las Cuentas corrientes registradas para el proveedor actual-
        /// </summary>
        /// <returns>
        /// Un <see cref="List<ECuentasCorrientes>"/> con todas las Cuentas corrientes registradas.
        /// </returns>
        public List<ECuentasCorrientes> GetAccount()
        {
            return this.listCta;
        }

        /// <summary>
        /// Obtiene la informacion de la cuenta corriente segun el codigo indicado.
        /// </summary>
        /// <param name="item">Id de la cuente corriente a buscar.</param>
        /// <returns>Un <see cref="ECuentasCorrientes"/> si el Id existe, de lo contrario null.</returns>
        public ECuentasCorrientes GetAccount(int item)
        {
            return this.listCta.Find(delegate(ECuentasCorrientes cta)
            {
                return (cta.IdCtaCte == item);
            });
        }

        public ECuentasCorrientes GetCtsAccount()
        {
            return listCta.Find(delegate(ECuentasCorrientes c)
            {
                return c.IdTipoCtaCte == 2;
            });
        }

        public ECuentasCorrientes GetSueldoAccount()
        {
            return listCta.Find(delegate(ECuentasCorrientes c)
            {
                return c.IdTipoCtaCte ==1;
            });
        }
        private object GetObget(int intVal) {
            if (intVal < 0)
            {
                return DBNull.Value;
            }
            else {
                return intVal;
            }
        }
        public object[] ToObject(int operacion,EnumTipoPersona persona)
        {
            object[] objCliente = new object[]
            {
              
                this.IdPersona,//_id_persona
                this.NumeroDocumento,//_doc_persona
                this.Nombres , //_nom_persona
                this.Apellidos , //_ape_persona
                this.FullName , //_fullname_persona
                this.Observacion,//_obs_presona
                this.IdEstado,//_id_estado
                this.RazonSocial,//_rs_persona
                this.NombreComercial,//_nom_com_persona
                this.IdEstadoCivil , //_est_civ_persona
                this.FechaNacimiento.Date,//_fecnac_persona
                this.Sexo,//_sex_persona
                this.TipoPersonaSistema,//_tipo_per_sistema
                this.IdTipoDocumento,//_id_documento
                GetObget (this.IdArea ),//id_area
                GetObget (this.IdCargo ),//_id_cargo
                GetObget (this.IdProfesion ),//id_profecion
                GetObget (this .IdGradoInstruccion ),//id_grado_instruccion                
                this.LugarNacimiento , //lug_nacimiento
                GetObget (this.IdTipoProveedor ), //1,//null, id_tipo_proveedor
                GetObget ( this.IdTipoCliente),//_id_tipo_cliente
                Convert.ToInt32(this.IsDeudaConfidencial), // this.IsDeudaConfidencial, 
                Convert.ToInt32(this.CreditoNoDisponible), //this.CreditoNoDisponible, 
                operacion,
               (int) persona 
            };
            return objCliente;
        }

        #endregion
    }
}